﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Speech.Recognition;

namespace CodeTalk.CTSpeechCommands
{
    class DictationCommand : SpeechCommand
    {
        private enum DictationType
        {
            Text,
            String,
            Comment,
            Todo,
            Summary,

            nDictationTypes
        }

        internal override GrammarBuilder GrammarBld(Context context, Context[] libraries)
        {
            Choices c = new Choices();
            for (int i = 0; i < (int)DictationType.nDictationTypes; i++)
                c.Add(new SemanticResultValue(((DictationType)i).ToString(), i));

            GrammarBuilder gb = new GrammarBuilder("dictate");
            gb.Append(new SemanticResultKey("DictationType", c));
            gb.AppendDictation();
            return gb;
        }

        public override string Name
        {
            get { return "Dictate {text|string|comment|todo|summary}"; }
        }

        public override string Description
        {
            get { return Name; }
        }

        private string GetTextToWrite(string dictatedText, DictationType type, out string undoString)
        {
            dictatedText = TextUtilz.CapFirstLetter(dictatedText);
            if (type == DictationType.Text)
            {
                undoString = "^z";
                return dictatedText;
            }
            else if (type == DictationType.String)
            {
                undoString = "^z";
                return "\"" + dictatedText + "\"";
            }
            else if (type == DictationType.Comment)
            {
                undoString = "^z";
                return "// " + dictatedText;
            }
            else if (type == DictationType.Todo)
            {
                undoString = "^z";
                return "// TODO: " + dictatedText;
            }
            else
            {
                undoString = "^z^z^z";
                return "///" + dictatedText;
            }
        }

        public override string GetAlternativesFeedback(string recognizedText, SemanticValue semValue)
        {
            string us;
            DictationType dicType = (DictationType)((int)semValue["DictationType"].Value);
            return GetTextToWrite(recognizedText.Substring(9 + dicType.ToString().Length), dicType, out us);
        }

        internal override bool CanSpokenFormMatch(string spokenForm)
        {
            if (spokenForm.StartsWith("dictate text ") || 
                spokenForm.StartsWith("dictate string ") ||
                spokenForm.StartsWith("dictate comment ") ||
                spokenForm.StartsWith("dictate todo ") ||
                spokenForm.StartsWith("dictate summary "))
                return true;

            return false;
        }

        internal override object Execute(SpeechMode callingMode, string recognizedText, SemanticValue semValue)
        {
            try
            {
                DictationType dicType = (DictationType)((int)semValue["DictationType"].Value);
                string undoString;
                string textToWrite = GetTextToWrite(recognizedText.Substring(9 + dicType.ToString().Length), dicType, out undoString);

                callingMode.CurrentOutputHandler.SendKeys(textToWrite);
                callingMode.CurrentGuiHandler.SetPrimaryFeedback(textToWrite);
                return undoString;
            }
            catch (Exception ex)
            {
                callingMode.CurrentGuiHandler.SetErrorFeedback("Internal error in NewVariable: " + ex);
                return null;
            }
        }
    }
}
